package org.tigris.atlas.xml.schema.mda.element;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.tigris.atlas.mda.PackageManager;
import org.tigris.atlas.mda.metadata.element.Field;
import org.tigris.atlas.mda.metadata.element.Reference;

public class SchemaReference implements Reference, NamespaceAware {
	
	private Reference reference;
	private List decoratedFoerignKeyFieldList;
	
	/**
	 * Create a new instance of <tt>Reference</tt> with the correct functionality set 
	 * to generate Schema code
	 * @param referenceToDecorate The <tt>Reference</tt> to decorate
	 */
	public SchemaReference(Reference referenceToDecorate) {
		if (referenceToDecorate == null) {
			throw new IllegalArgumentException("SchemaReferences must be instatiated with a non-null reference!");
		}
		reference = referenceToDecorate;
	}	

	public String getType() {
		return reference.getType();
	}

	public String getLabel() {
		return reference.getLabel();
	}

	public String getName() {
		return reference.getName();
	}
	
	public String getDocumentation() {
		return reference.getDocumentation();
	}

	public String getCapitalizedName() {
		return StringUtils.capitalize(reference.getName());
	}

	public List getForeignKeyFields() {
		if (decoratedFoerignKeyFieldList == null) {
			List referenceForeignKeyFieldList = reference.getForeignKeyFields();
			if ((referenceForeignKeyFieldList == null) || (referenceForeignKeyFieldList.size() == 0)) {
				decoratedFoerignKeyFieldList = Collections.EMPTY_LIST;
				
			} else {
				Field f;
				decoratedFoerignKeyFieldList = new ArrayList((int)(referenceForeignKeyFieldList.size()));
				Iterator i = referenceForeignKeyFieldList.iterator();
				while (i.hasNext()) {
					f = (Field)i.next();
					decoratedFoerignKeyFieldList.add(new SchemaField(f));
					
				}
				
			}
		}
		
		return decoratedFoerignKeyFieldList;
	}

	public String getRequired() {
		return reference.getRequired();
	}

	public boolean isRequired() {
		return reference.isRequired();
	}

	public String getProject() {		
		return reference.getProject();
	}
	
	public boolean isExternal() {
		return (getProject() != null);
	}

	//////////////////////////////////////////////////////////////////////
	//schema-specific methods:
	//////////////////////////////////////////////////////////////////////
	
	/**
	 * Returns the schema type for this entity
	 */
	public String getSchemaType() {		
		return SchemaElementUtils.getComplexTypeSchemaType(getType());
	}
	
	/**
	 * Return namespace name of this instance (ie, the 'xs' part of 'xmlns:xs')
	 */
	public String getNamespaceName() {
		String name = SchemaElementUtils.getNamespaceName(getProject(), getType());
		return name;
	}
	
	/**
	 * Returns relative location of the namespace
	 */
	public String getNamespaceLocation() {
		String location = SchemaElementUtils.getNamespaceLocation(getProject(), getType());
		return location;
	}
	
	/**
	 * Returns relative location of the namespace
	 */
	public String getBase() {
		String basePackage = PackageManager.getBasePackage( getProject() );
		String baseNamespace = SchemaElementUtils.translateBasePackageToBaseSchemaLocation(basePackage); 
		return baseNamespace;
	}
	
	public String getExternalProjectBaseNamespace(String leftToRightNamespace) {
		String baseSchemaLocation = SchemaElementUtils.translateBasePackageToBaseSchemaLocation(leftToRightNamespace);
		return baseSchemaLocation;
	}
	
}
